# encoding:utf-8
"""
@file = layuimixins
@author = zouju
@create_time = 2023-08-31- 8:05
layuimixins.py在mixins.py基础上封装layui格式的返回值

Basic building blocks for generic class based views.

We don't bind behaviour to http method handlers yet,
which allows mixin classes to be composed in interesting ways.
"""
import json

from rest_framework.decorators import action
from rest_framework.generics import get_object_or_404
from rest_framework.response import Response
from rest_framework.settings import api_settings

from common.API import res_josn_data
from common.API.log import exec_log
from common.filter.format import vague_filter


class CreateModelMixin:
    """
    Create a model instance.
    """

    def create(self, request, *args, **kwargs):
        print('request.data:', request.data)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        exec_log(request, is_access=True, desc=serializer.data)
        return res_josn_data.table_success(msg='创建成功', data=serializer.data)

    def perform_create(self, serializer):
        serializer.save()

    def get_success_headers(self, data):
        try:
            return {'Location': str(data[api_settings.URL_FIELD_NAME])}
        except (TypeError, KeyError):
            return {}


class ListModelMixinLayui:
    """
    List a queryset.
    """

    def list(self, request, *args, **kwargs):
        page = request.GET.get('page', 1)
        limit = request.GET.get('limit', 10)
        post_data_str = request.GET.get('Params', None)
        number = (int(page) - 1) * int(limit)  # 每页开始的序号

        if post_data_str is None:
            return res_josn_data.table_api(data=[])
        json_data = json.loads(post_data_str)
        filters = vague_filter(json_data)   # 生成过滤器参数
        print('filters:', filters)
        queryset = self.get_serializer_class().Meta.model.objects.filter(**filters).order_by('-id')  # 过滤
        page = self.paginate_queryset(queryset)  # 分页
        serializer = self.get_serializer(queryset, many=True)  # 序列化

        if page is None:
            return res_josn_data.table_api(data=[])
        else:
            serializer_page = self.get_serializer(page, many=True)

            # print('返回数据:', serializer.data)
            return res_josn_data.table_api(count=len(serializer.data), data=serializer_page.data, number=number)


class RetrieveModelMixin:
    """
    Retrieve a model instance.
    """

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)


class UpdateModelMixinLayui:
    """
    Update a model instance.
    """

    def update(self, request, *args, **kwargs):
        print('put request.data:', request.data)
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        # return Response(serializer.data)
        exec_log(request, is_access=True, desc=serializer.data)
        print('更新serializer.data:', serializer.data)
        return res_josn_data.success_api('更新成功')

    @action(methods=['put'], detail=False)
    def enable(self, request, *args, **kwargs):  # 自定义方法,局部更新时序列化器数据验证报错
        enable_dict = {'enable': 1, 'disable': 0}
        enable_dict_cn = {'enable': '启用', 'disable': '禁用'}
        post_data_str = request.POST
        print('post_data_str:', post_data_str)
        field_id = request.POST.get('id', None)
        enable_value = request.POST.get('enable', None)  # 0禁用 1启用
        instance = self.get_serializer_class().Meta.model.objects.filter(id=field_id)
        instance.update(**{'enable': enable_dict[enable_value]})
        exec_log(request, is_access=True, desc=f'ID:{field_id} {enable_dict_cn[enable_value]}成功')
        return res_josn_data.success_api(msg=f'{enable_dict_cn[enable_value]}成功')

    def perform_update(self, serializer):
        serializer.save()

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)


class DestroyModelMixinLayui:
    """
    Destroy a model instance.
    """

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.delete()
        print(f'id:{instance} 已删除')
        exec_log(request, is_access=True, desc=f'{instance} 已删除')
        # return Response(status=status.HTTP_204_NO_CONTENT)
        return res_josn_data.success_api('删除成功')

    def perform_destroy(self, instance):
        instance.delete()

    @action(methods=['delete'], detail=False)
    def multiple_delete(self, request, *args, **kwargs):
        post_data_str = request.POST.get('Params', None)
        post_data = json.loads(post_data_str)
        # pks = request.query_params.get('pks', None)  # 获取要删除的对象们的主键值
        # if not pks:
        #     return Response(status=status.HTTP_404_NOT_FOUND)
        for item in post_data:
            id_value = item['id']
            queryset = self.filter_queryset(self.get_queryset())
            instance = get_object_or_404(queryset, id=int(id_value))
            instance.delete()
            print(f'id:{id_value} 已删除')
            exec_log(request, is_access=True, desc=f'id:{id_value} 已删除')
        return res_josn_data.success_api('删除成功')
        # return Response(status=status.HTTP_204_NO_CONTENT)
